<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
    <title>Chapter 3: Configuration</title>

    <link rel="stylesheet" type="text/css" href="../css/site.css" />

  </head>
  <body onload="prettyPrint(); decorate();">

    <script type="text/javascript">prefix='../'</script>
    <script type="text/javascript" src="../js/prettify.js"></script>
    <script type="text/javascript" src="../js/jquery-min.js"></script>
    <script type="text/javascript" src="../js/decorator.js"></script>

    <div id="container">
      <script type="text/javascript" src="../templates/header.js"></script>      
      
      <div id="left">
        <noscript>Please turn on Javascript to view this menu</noscript>
        <script src="../templates/left.js" type="text/javascript"></script>
      </div>

      <div id="right">
        <script src="menu.js" type="text/javascript"></script>
      </div>

      <div id="content">
      
    <h1>Chapter 3: Logback configuration</h1>

    <div class="quote">
      <p><em>In symbols one observes an advantage in discovery which
      is greatest when they express the exact nature of a thing
      briefly and, as it were, picture it; then indeed the labor of
      thought is wonderfully diminished.</em>
      </p>
      <p>&mdash;GOTTFRIED WILHELM LEIBNIZ</p>
    </div>


    <script src="../templates/creative.js" type="text/javascript"></script>

    <p>We start by presenting ways for configuring logback, with many
    example configuration scripts.  Joran, the configuration framework
    upon which logback relies will be presented in <a
    href="onJoran.html">a later chapter</a>.
    </p>


    <h2 class="doAnchor" name="auto_configuration">Configuration in
    logback</h2>
    
    <p>Inserting log requests into the application code requires a
    fair amount of planning and effort. Observation shows that
    approximately four percent of code is dedicated to
    logging. Consequently, even a moderately sized application will
    contain thousands of logging statements embedded within its
    code. Given their number, we need tools to manage these log
    statements.
    </p>

    <p>Logback can be configured either programmatically or with a
    configuration script expressed in XML or Groovy format. By the
    way, existing log4j users can convert their
    <em>log4j.properties</em> files to <em>logback.xml</em> using our
    <a
    href="http://logback.qos.ch/translator/">PropertiesTranslator</a>
    web-application.
    </p>

    <p>Let us begin by discussing the initialization steps that
    logback follows to try to configure itself:
    </p>

    <ol>

      <li>
        <p>Logback tries to find a file called
        <em>logback-test.xml</em> <a
        href="../faq.html#configFileLocation">in the
        classpath</a>.</p> </li>


      <li><p>If no such file is found, it checks for the file
      <em>logback.xml</em>  <a
        href="../faq.html#configFileLocation">in the
        classpath</a>..</p>
      </li>
      
      <li><p>If no such file is found, <a
      href="http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html">
      service-provider loading facility</a> (introduced in JDK 1.6) is
      used to resolve the implementation of <a
      href="../xref/ch/qos/logback/classic/spi/Configurator.html">
      <code>com.qos.logback.classic.spi.Configurator</code></a>
      interface by looking up the file
      <em>META-INF\services\ch.qos.logback.classic.spi.Configurator</em>
      in the class path. Its contents should specify the fully
      qualified class name of the desired <code>Configurator</code>
      implementation. 
      </p>
      </li>
      
      <li><p>If none of the above succeeds, logback configures itself
      automatically using the <a
      href="../xref/ch/qos/logback/classic/BasicConfigurator.html"><code>BasicConfigurator</code></a>
      which will cause logging output to be directed to the console.
      </p> 
      </li> 

    </ol>

    <p>The last step is meant as last-ditch effort to provide a
    default (but very basic) logging functionality in the absence of a
    configuration file.
    </p>

    <p><span class="label notice">Groovy</span> Given that Groovy is a
    full-fledged language, we have dropped support for
    <em>logback.groovy</em> in order to protect the innocent.
    </p>
    
    <p>If you are using Maven and if you place the
    <em>logback-test.xml</em> under the <em>src/test/resources</em>
    folder, Maven will ensure that it won't be included in the
    artifact produced. Thus, you can use a different configuration
    file, namely <em>logback-test.xml</em> during testing, and another
    file, namely, <em>logback.xml</em>, in production. 
    </p>

    <p><span class="label">Fast start-up</span> It takes about 100
    miliseconds for Joran to parse a given logback configuration
    file. To shave off those miliseconds at aplication start up, you
    can use the service-provider loading facility (item 4 above) to
    load your own custom <code>Configurator</code> class with <a
    href="../xref/ch/qos/logback/classic/BasicConfigurator.html">BasicConfigrator</a>
    serving as a good starting point.</p>


    <h3 class="doAnchor" name="automaticConf">Automatically
    configuring logback</h3>

    <p>The simplest way to configure logback is by letting logback
    fall back to its default configuration. Let us give a taste of how
    this is done in an imaginary application called
    <code>MyApp1</code>.
    </p>

    <p class="example">Example: Simple example of
    <code>BasicConfigurator</code> usage <a
    href="../xref/chapters/configuration/MyApp1.html">(logback-examples/src/main/java/chapters/configuration/MyApp1.java)</a></p>

    <pre class="prettyprint source">package chapters.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyApp1 {
  final static Logger logger = LoggerFactory.getLogger(MyApp1.class);

  public static void main(String[] args) {
    logger.info("Entering application.");

    Foo foo = new Foo();
    foo.doIt();
    logger.info("Exiting application.");
  }
}</pre>

  <p>This class defines a static logger variable. It then instantiates
  a <code>Foo</code> object. The <code>Foo</code> class is listed
  below:
  </p>

  <p class="example">Example: Small class doing logging 
  <a href="../xref/chapters/configuration/Foo.html">(logback-examples/src/main/java/chapters/configuration/Foo.java)</a>
  </p>

  <pre class="prettyprint source">package chapters.configuration;
  
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
   
public class Foo {
  static final Logger logger = LoggerFactory.getLogger(Foo.class);
  
  public void doIt() {
    logger.debug("Did it again!");
  }
}</pre>


    <p>In order to run the examples in this chapter, you need to make
    sure that certain jar files are present on the class path.  Please
    refer to the <a href="../setup.html">setup page</a> for further
    details.
    </p>

    <p>Assuming the configuration files <em>logback-test.xml</em> or
    <em>logback.xml</em> are not present, logback will default to
    invoking <a
    href="../xref/ch/qos/logback/classic/BasicConfigurator.html"><code>BasicConfigurator</code></a>
    which will set up a minimal configuration. This minimal
    configuration consists of a <code>ConsoleAppender</code> attached
    to the root logger.  The output is formatted using a
    <code>PatternLayoutEncoder</code> set to the pattern
    <em>%d{HH:mm:ss.SSS}&nbsp;[%thread]&nbsp;%-5level&nbsp;%logger{36}&nbsp;-&nbsp;%msg%n</em>. Moreover,
    by default the root logger is assigned the <code>DEBUG</code>
    level.
    </p>

    <p>Thus, the output of the command <em>java chapters.configuration.MyApp1</em>
    should be similar to:
    </p>

    <p class="source">16:06:09.031 [main] INFO  chapters.configuration.MyApp1 - Entering application.
16:06:09.046 [main] DEBUG chapters.configuration.Foo - Did it again!
16:06:09.046 [main] INFO  chapters.configuration.MyApp1 - Exiting application.</p>


   <p class="highlight">Except code that configures logback (if such
   code exists) client code does not need to depend on
   logback. Applications that use logback as their logging framework
   will have a compile-time dependency on SLF4J but not logback.
   </p>

   <p>The <code>MyApp1</code> application links to logback via calls
   to <code>org.slf4j.LoggerFactory</code> and
   <code>org.slf4j.Logger</code> classes, retrieve the loggers it
   wishes to use, and chugs on.  Note that the only dependencies of
   the <code>Foo</code> class on logback are through
   <code>org.slf4j.LoggerFactory</code> and
   <code>org.slf4j.Logger</code> imports.  Except code that configures
   logback (if such code exists) client code does not need to depend
   on logback. Since SLF4J permits the use of any logging
   framework under its abstraction layer, it is easy to migrate
   large bodies of code from one logging framework to another.
   </p>

   <h3>Automatic configuration with <em>logback-test.xml</em> or
   <em>logback.xml</em></h3>

   <p>As mentioned earlier, logback will try to configure itself using
   the files <em>logback-test.xml</em> or <em>logback.xml</em> if
   found on the class path. Here is a configuration file equivalent to
   the one established by <code>BasicConfigurator</code> we've just
   seen.
   </p>

   <p class="example">Example: Basic configuration file
   (logback-examples/src/main/resources/chapters/configuration/sample0.xml)</p>

  <pre id="sample0" class="prettyprint source">&lt;configuration>

  &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    &lt;!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    &lt;encoder>
      &lt;pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="debug">
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>
&lt;/configuration></pre>

   <p>After you have renamed <em>sample0.xml</em> as
   <em>logback.xml</em> (or <em>logback-test.xml</em>) place it into a
   directory accessible from the class path. Running the <em>MyApp1</em>
   application should give identical results to its previous run.</p>

   
   <h4 class="doAnchor" name="automaticStatusPrinting">Automatic
   printing of status messages in case of warning or errors</h4>

   <p class="highlight">If warning or errors occur during the parsing
   of the configuration file, logback will automatically print its
   internal status messages on the console.</p>
 
   <p>If warnings or errors occur during the parsing of the
   configuration file, logback will automatically print its internal
   status data on the console. Note that to avoid duplication,
   automatic status printing is disabled if the user explicitly
   registers a status listener (<a href="#logback.statusLC">discussed
   below</a>).</p>

   <p>In the absence of warnings or errors, if you still wish to
   inspect logback's internal status, then you can instruct logback to
   print status data by invoking the <code>print()</code> of the
   <code>StatusPrinter</code> class. The <em>MyApp2</em> application
   shown below is identical to <em>MyApp1</em> except for the addition
   of two lines of code for printing internal status data.</p>

   <p class="example" id="MyApp2">Example: Print logback's internal status
    information <a
    href="../xref/chapters/configuration/MyApp2.html">(logback-examples/src/main/java/chapters/configuration/MyApp2.java)</a></p>

  
<pre class="prettyprint lang-java source">
public static void main(String[] args) {
  // assume SLF4J is bound to logback in the current environment
  <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
  // print logback's internal status
  <b>StatusPrinter.print(lc);</b>
  ...
}</pre>

  <p>If everything goes well, you should see the following output on the console</p>

  <div class="source longline">17:44:58,578 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml]
17:44:58,671 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
17:44:58,671 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
17:44:58,687 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Popping appender named [STDOUT] from the object stack
17:44:58,812 |-INFO in ch.qos.logback.classic.joran.action.LevelAction - root level set to DEBUG
17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[root]

17:44:58.828 [main] INFO  chapters.configuration.MyApp2 - Entering application.
17:44:58.828 [main] DEBUG chapters.configuration.Foo - Did it again!
17:44:58.828 [main] INFO  chapters.configuration.MyApp2 - Exiting application.
</div>

  <p>At the end of this output, you can recognize the lines that were
  printed in the previous example. You should also notice the
  logback's internal messages, a.k.a. <code>Status</code> objects,
  which allow convenient access to logback's internal state.
  </p>

   <h4 class="doAnchor" name="dumpingStatusData">Status data</h4>

   <p class="highlight">Enabling output of status data usually goes a
   long way in the diagnosis of issues with logback.</p>

   <p>Enabling output of status data usually goes a
   long way in the diagnosis of issues with logback. Note that errors
   can also occur post-configuration, e.g. when a disk a full or log
   files cannot be archived due to permission errors. As such, it is
   highly recommended that you register a <code>StatusdListener</code>
   as discussed below.</p>

   <p>The next example illustrates the installation of
   <code>OnConsoleStatusListener</code>. </p>

   <p class="example">Example: Registering a status listener
   (logback-examples/src/main/resources/chapters/configuration/onConsoleStatusListener.xml)</p>

   <pre id="onConsoleStatusListener" class="prettyprint source">&lt;configuration>
  &lt;-- Recommendation: place status listeners towards the the top of the configuration file --&gt;
  <b>&lt;statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /></b>  

  ... the rest of the configuration file  
&lt;/configuration></pre>

   <p>A <code>StatusListner</code> can be installed using a
   configuration fileassuming that:
   </p>
   <ol>
     <li>the configuration file is found</li>
     <li>the configuration file is well-formed XML.</li>
   </ol>

     
   <p>If any of these two conditions is not fulfilled, Joran cannot
   interpret the configuration file and in particular the
   &lt;statusListener/&gt; element. If the configuration file is found
   but is malformed, then logback will detect the error condition and
   automatically print its internal status on the console. However, if
   the configuration file cannot be found, logback will not
   automatically print its status data, since this is not necessarily
   an error condition. Programmatically invoking
   <code>StatusPrinter.print()</code> as shown in the <a
   href="#MyApp2"><em>MyApp2</em></a>
   application above ensures that status information is printed in
   every case.</p>
 
   <p><span class="label">Forcing status output</span> In the absence
   of status messages, tracking down a rogue <em>logback.xml</em>
   configuration file can be difficult, especially in production where
   the application source cannot be easily modified. To help identify
   the location of a rogue configuration file, you can set a
   <code>StatusListener</code> via the "logback.statusListenerClass"
   system property (<a href="#logback.statusLC">discussed below</a>) to
   force output of status messages. The "logback.statusListenerClass"
   system property can also be used to silence output automatically
   generated in case of errors.
   </p>

   
   <h4>Shorthand</h4>
   
   <p>As a shorthand, it is possible to register an
   <code>OnConsoleStatusListener</code> by setting the <em>debug</em>
   attribute to <code>true</code> within the &lt;configuration/&gt;
   element as shown below.</p>

  <p class="example">Example: Basic configuration file using debug
   mode
   (logback-examples/src/main/resources/chapters/configuration/sample1.xml)</p>

   <pre id="sample1" class="prettyprint source">
&lt;configuration <span class="bold">debug="true"</span>> 

  &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
    &lt;&excl;&dash;- encoders are  by default assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder &dash;&dash;>
    &lt;encoder>
      &lt;pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="debug">
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>
&lt;/configuration></pre>
  
   <p>By the way, setting <code>debug="true"</code> is strictly
   equivalent to installing an <code>OnConsoleStatusListener</code> as
   shown previously. </p>


   <h3 class="doAnchor"
   name="logback.statusLC">"logback.statusListenerClass" system
   property</h3>

   <p>One may also register a status listener by setting the
   "logback.statusListenerClass" Java system property to the name of
   the listener class you wish to register. For example,
   </p>

   <p class="source">java <b>-Dlogback.statusListenerClass</b>=ch.qos.logback.core.status.OnConsoleStatusListener&nbsp;...</p>
   
   <p>Logback ships with several status listener implementations. <a
   href="../xref/ch/qos/logback/core/status/OnConsoleStatusListener.html">OnConsoleStatusListener</a>
   prints incoming status messages on the console, i.e. on
   System.out. <a
   href="../xref/ch/qos/logback/core/status/OnErrorConsoleStatusListener.html">OnErrorConsoleStatusListener</a>
   prints incoming status messages on System.err. <a
   href="../xref/ch/qos/logback/core/status/NopStatusListener.html">NopStatusListener</a>
   drops incoming status messages.</p>
   

   <p>Note that <a href="#automaticStatusPrinting">automatic status
   printing</a> (in case of errors) is disabled if any status listener
   is registered during configuration and in particular if the user
   specifies a status listener via the "logback.statusListenerClass"
   system. Thus, by setting <code>NopStatusListener</code> as a status
   listener, you can silence internal status printing altogether. </p>
   
   <p class="source">java <b>-Dlogback.statusListenerClass</b>=ch.qos.logback.core.status.NopStatusListener&nbsp;...</p>

   <h3 class="doAnchor" name="viewingStatusMessages">Viewing status
   messages </h3>

   <p>Logback collects its internal status data in a <code><a
   href="../xref/ch/qos/logback/core/status/StatusManager.html">StatusManager</a></code>
   object, accessible via the <code>LoggerContext</code>.
   </p>

   <p>Given a <code>StatusManager</code> you can access all the status
   data associated with a logback context. To keep memory usage at
   reasonable levels, the default <code>StatusManager</code>
   implementation stores the status messages in two separate parts:
   the header part and the tail part. The header part stores the first
   <em>H</em> status messages whereas the tail part stores the last
   <em>T</em> messages. At present time <em>H</em>=<em>T</em>=150,
   although these values may change in future releases.</p>

   <p>Logback-classic ships with a servlet called
   ViewStatusMessagesServlet. This servlet prints the contents of the
   <code>StatusManager</code> associated with the current
   <code>LoggerContext</code> as an HTML table. Here is sample output.
   </p>
   
   <a href="images/chapters/configuration/lbClassicStatus.jpg">
     <img src="images/chapters/configuration/lbClassicStatus.jpg" alt="click to enlarge" width="90%"/>
   </a>

   <p>To add this servlet to your web-application, add the following
   lines to its <em>WEB-INF/web.xml</em> file.</p>

   <pre class="prettyprint source">  &lt;servlet>
    &lt;servlet-name>ViewStatusMessages&lt;/servlet-name>
    &lt;servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet&lt;/servlet-class>
  &lt;/servlet>

  &lt;servlet-mapping>
    &lt;servlet-name>ViewStatusMessages&lt;/servlet-name>
    &lt;url-pattern>/lbClassicStatus&lt;/url-pattern>
  &lt;/servlet-mapping></pre>
   
   <p>The <code>ViewStatusMessages</code> servlet will be viewable at
   the URL <code>http://host/yourWebapp/lbClassicStatus</code>
   </p>


   <h3 class="doAnchor" name="statusListenerViaCode">Listening to status messages via code</h3>

   <p>You may also register a <code>StatusListener</code> via Java
   code. Here is <a
   href="../xref/chapters/configuration/AddStatusListenerApp.html">sample
   code</a>. </p>

   <pre class="prettyprint source">   LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 
   StatusManager statusManager = lc.getStatusManager();
   OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener();
   statusManager.add(onConsoleListener);</pre>

   <p>Note that the registered status listener will only receive status
   events subsequent to its registration. It will not receive prior
   messages. Thus, it is usually a good idea to place status listener
   registration directives at top of the configuration file before
   other directives.</p>

      

   <!-- =========================================================== -->

   <h2 class="doAnchor" name="configFileProperty">Setting the location
   of the configuration file via a system property</h2>

   <p>You may specify the location of the default configuration file
   with a system property named
   <code>"logback.configurationFile"</code>. The value of this
   property can be a URL, a resource on the class path or a path to a
   file external to the application.
   </p>

   <p class="source">java <b>-Dlogback.configurationFile=/path/to/config.xml</b> chapters.configuration.MyApp1</p>

   <p>Note that the file extension must be ".xml" or ".groovy". Other
   extensions are ignored. <a href="#logback.statusLC">Explicitly
   registering a status listener</a> may help debugging issues
   locating the configuration file.</p>

   <p>Given that <code>"logback.configurationFile"</code> is a Java
   system property, it may be set within your application as
   well. However, the system property must be set before any logger
   instance is created.</p>

   <pre class="prettyprint lang-java source">import ch.qos.logback.classic.util.ContextInitializer;

public class ServerMain {
    public static void main(String args[]) throws IOException, InterruptedException {
       // must be set before the first call to  LoggerFactory.getLogger();
       // ContextInitializer.CONFIG_FILE_PROPERTY is set to "logback.configurationFile"
       System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "/path/to/config.xml");
       ...
    }   
}</pre>
   
   <h3 class="doAnchor" name="autoScan">Automatically reloading
   configuration file upon modification</h3>

   <p class="highlight">Logback-classic can scan for changes in its
   configuration file and automatically reconfigure itself when the
   configuration file changes.</p>

   <p>If instructed to do so, logback-classic will scan for changes in
   its configuration file and automatically reconfigure itself when
   the configuration file changes. In order to instruct
   logback-classic to scan for changes in its configuration file and
   to automatically re-configure itself set the <span
   class="attr">scan</span> attribute of the
   <code>&lt;configuration></code> element to true, as shown next.

   </p>
  
   <p class="example">Example: Scanning for changes in configuration
   file and automatic re-configuration
   (logback-examples/src/main/resources/chapters/configuration/scan1.xml)</p>

<pre id="scan1" class="prettyprint source">
&lt;configuration <b>scan="true"</b>> 
  ... 
&lt;/configuration> </pre>


   <p>By default, the configuration file will be scanned for changes
   once every minute. You can specify a different scanning period by
   setting the <span class="attr">scanPeriod</span> attribute of the
   <code>&lt;configuration></code> element. Values can be specified in
   units of milliseconds, seconds, minutes or hours. Here is an
   example:</p>

  <p class="example">Example: Specifying a different scanning period
  (logback-examples/src/main/resources/chapters/configuration/scan2.xml)</p>

  <pre id="scan2" class="prettyprint source">
&lt;configuration scan="true" <b>scanPeriod="30 seconds"</b> > 
  ...
&lt;/configuration> </pre>

   <p><span class="label">Note</span> If no unit of time is specified,
   then the unit of time is assumed to be milliseconds, which is
   usually inappropriate. If you change the default scanning period,
   do not forget to specify a time unit.
   </p>

   <p>Behind the scenes, when you set the <span
   class="option">scan</span> attribute to <code>true</code>, a <a
   href="../xref/ch/qos/logback/classic/joran/ReconfigureOnChangeTask.html"><code>ReconfigureOnChangeTask</code></a>
   will be installed. This task run in a separate thread and will
   check whether your configuration file has
   changed. <code>ReconfigureOnChangeTask</code> will automatically
   watch for any <a href="#fileInclusion">included</a> files as
   well.</p>

   <p>As it is easy to make errors while editing a configuration file,
   in case the latest version of the configuration file has XML syntax
   errors, it will fall back to a previous configuration file free of
   XML syntax errors.</p>

   
   <h4 class="doAnchor" name="packagingData">Enabling packaging data in stack traces</h4>

   <p class="highlight">While useful, packaging data is expensive to
   compute, especially in applications with frequent exceptions.</p>

   <p><span class="label notice">NOTE</span> As of version 1.1.4,
   packaging data is disabled by default. </p>

   <p>If instructed to do so, logback can include packaging data for
   each line of the stack trace lines it outputs. Packaging data
   consists of the name and version of the jar file whence the class
   of the stack trace line originated. Packaging data can be very
   useful in identifying software versioning issues. However, it is
   rather expensive to compute, especially in application where
   exceptions are thrown frequently. Here is a sample output:</p>

   <pre>14:28:48.835 [btpool0-7] INFO  c.q.l.demo.prime.PrimeAction - 99 is not a valid value
java.lang.Exception: 99 is invalid
  at ch.qos.logback.demo.prime.PrimeAction.execute(PrimeAction.java:28) [classes/:na]
  at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431) <b>[struts-1.2.9.jar:1.2.9]</b>
  at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236) [struts-1.2.9.jar:1.2.9]
  at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) [struts-1.2.9.jar:1.2.9]
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) <b>[servlet-api-2.5-6.1.12.jar:6.1.12]</b>
  at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502) [jetty-6.1.12.jar:6.1.12]
  at ch.qos.logback.demo.UserServletFilter.doFilter(UserServletFilter.java:44) [classes/:na]
  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115) <b>[jetty-6.1.12.jar:6.1.12]</b>
  at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361) [jetty-6.1.12.jar:6.1.12]
  at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417) [jetty-6.1.12.jar:6.1.12]
  at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230) [jetty-6.1.12.jar:6.1.12]</pre>


  <p>Packaging data is disabled by default but can be enabled by
  configuration:</p>

<pre class="prettyprint source">
&lt;configuration <span class="big bold">packagingData="true"</span>>
  ...
&lt;/configuration></pre>

   <p>Alternatively, packaging data can be enabled/disabled
   programmatically by invoking the <a
   href="../apidocs/ch/qos/logback/classic/LoggerContext.html#setPackagingDataEnabled(boolean)">setPackagingDataEnabled(boolean)</a>
   method in <code>LoggerContext</code>, as shown next:</p>


<pre class="prettyprint lang-java source">
  LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
  <b>lc.setPackagingDataEnabled(true);</b>
</pre>

   <h3 class="doAnchor" name="joranDirectly">Invoking
   <code>JoranConfigurator</code> directly</h3>

   <p>Logback relies on a configuration library called Joran, part of
   logback-core. Logback's default configuration mechanism invokes
   <code>JoranConfigurator</code> on the default configuration file it
   finds on the class path. If you wish to override logback's default
   configuration mechanism for whatever reason, you can do so by
   invoking <code>JoranConfigurator</code> directly. The next
   application, <em>MyApp3</em>, invokes JoranConfigurator on a
   configuration file passed as a parameter.</p>
   
   <p class="example">Example: Invoking <code>JoranConfigurator</code>
   directly <a
   href="../xref/chapters/configuration/MyApp3.html">(logback-examples/src/main/java/chapters/configuration/MyApp3.java)</a></p>

<pre class="prettyprint source">package chapters.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;

public class MyApp3 {
  final static Logger logger = LoggerFactory.getLogger(MyApp3.class);

  public static void main(String[] args) {
    // assume SLF4J is bound to logback in the current environment
    <b>LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
    
    <b>try {
      JoranConfigurator configurator = new JoranConfigurator();
      configurator.setContext(context);
      // Call context.reset() to clear any previous configuration, e.g. default 
      // configuration. For multi-step configuration, omit calling context.reset().
      context.reset(); 
      configurator.doConfigure(args[0]);
    } catch (JoranException je) {
      // StatusPrinter will handle this
    }
    StatusPrinter.printInCaseOfErrorsOrWarnings(context);</b>

    logger.info("Entering application.");

    Foo foo = new Foo();
    foo.doIt();
    logger.info("Exiting application.");
  }
}</pre>

   <p>This application fetches the <code>LoggerContext</code>
   currently in effect, creates a new <code>JoranConfigurator</code>,
   sets the context on which it will operate, resets the logger
   context, and then finally asks the configurator to configure the
   context using the configuration file passed as a parameter to the
   application. Internal status data is printed in case of warnings or
   errors. Note that for multi-step configuration,
   <code>context.reset()</code> invocation should be omitted.</p>


   <h2 class="doAnchor" name="stopContext">Stopping
   logback-classic</h2>

   <p>In order to release the resources used by logback-classic, it is
   always a good idea to stop the logback context. Stopping the
   context will close all appenders attached to loggers defined by the
   context and stop any active threads in an orderly way. Please also
   read the section on "shutdown hooks" just below.</p>

<pre class="prettyprint lang-java source">
import org.sflf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
...

// assume SLF4J is bound to logback-classic in the current environment
<b>LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
<b>loggerContext.stop();</b></pre>

   <p>In web-applications the above code could be invoked from within
   the <a
   href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html#contextDestroyed(javax.servlet.ServletContextEvent)">contextDestroyed</a>
   method of <code>ServletContextListener</code> in order to stop
   logback-classic and release resources. Starting with version
   1.1.10, the appropriate <code>ServletContextListener</code> is
   installed automatically for you (<a href="#webShutdownHook">see just below</a>).
   </p>

   <h4 class="doAnchor" name="shutdownHook">Stopping logback-classic 
   via a shutdown hook</h4>
   
   <p>Installing a JVM shutdown hook is a convenient way for shutting
   down logback and releasing associated resources. 
   </p>


   <pre class="prettyprint source">&lt;configuration debug="true">
   &lt;!-- in the absence of the class attribute, assume 
   ch.qos.logback.core.hook.DefaultShutdownHook --&gt;
   <b>&lt;shutdownHook/></b>
  .... 
&lt;/configuration></pre>

   <p>Note that you may install a shutdown hook of your own making by
   setting the <span class="attr">class</span> attribute to correspond
   to your shutdown hook's class name.</p>
  
   <p>The default shutdown hook, namely <a
   href="../apidocs/ch/qos/logback/core/hook/DefaultShutdownHook.html">DefaultShutdownHook</a>,
   will <b>stop</b> the logback context after a specified delay (0 by
   default). Stopping the context will allow up to 30 seconds for any
   log file compression tasks running in the background to finish. In
   standalone Java applications, adding a
   <code>&lt;shutdownHook/></code> directive to your configuration
   file is an easy way to ensure that any ongoing compression tasks
   are allowed to finish before JVM exit. In applications within a Web
   server, <a href="#webShutdownHook">webShutdownHook</a> will be
   installed automatically making <code>&lt;shutdownHook/></code>
   directive quite redundant and unnecessary. </p>


 
    <h4 class="doAnchor" name="webShutdownHook">WebShutdownHook or stopping logback-classic 
   in web-applications</h4>
  
   <p><span class="label">since 1.1.10</span> Logback-classic will
   <b>automatically</b> ask the web-server to install a <code><a
   href="../apidocs/ch/qos/logback/classic/servlet/LogbackServletContainerInitializer.html">LogbackServletContainerInitializer</a></code>
   implementing the <code>ServletContainerInitializer</code> interface
   (available in servlet-api 3.x and later). This initializer will in
   turn install and instance of <code><a
   href="../apidocs/ch/qos/logback/classic/servlet/LogbackServletContextListener.html">LogbackServletContextListener</a></code>.
   This listener will stop the current logback-classic context when
   the web-app is stopped or reloaded.
   </p>

   <p>You may disable the automatic the installation of
   <code>LogbackServletContextListener</code> by setting a
   &lt;context-param> named
   <code>logbackDisableServletContainerInitializer</code> in your
   web-application's web.xml file. Here is the relevant snippet.</p>

   
<pre class="prettyprint source">&lt;web-app>
    &lt;context-param>
        &lt;param-name>logbackDisableServletContainerInitializer&lt;/param-name>
        &lt;param-value>true&lt;/param-value>
    &lt;/context-param>
    .... 
&lt;/web-app></pre>

    <p>Note that
    <code>logbackDisableServletContainerInitializer</code> variable
    can also be set as a Java system property an OS environment
    variable. The most local setting has priority, i.e. web-app first,
    system property second and OS environment last.</p>


   <!-- =================================================================== -->
   <!-- =================================================================== -->

   <h2 class="doAnchor" name="syntax">Configuration file syntax</h2>

   <p>As you have seen thus far in the manual with plenty of examples
   still to follow, logback allows you to redefine logging behavior
   without needing to recompile your code.  Indeed, you can easily
   configure logback so as to disable logging for certain parts of
   your application, or direct output to a UNIX Syslog daemon, to a
   database, to a log visualizer, or forward logging events to a
   remote logback server, which would log according to local server
   policy, for example by forwarding the log event to a second logback
   server.
   </p>
	
   <p>The remainder of this section presents the syntax of
   configuration files. 
   </p>

   <p>As will be demonstrated over and over, the syntax of logback
   configuration files is extremely flexible. As such, it is not
   possible to specify the allowed syntax with a DTD file or an XML
   schema. Nevertheless, the very basic structure of the configuration
   file can be described as, <code>&lt;configuration></code> element,
   containing zero or more <code>&lt;appender></code> elements,
   followed by zero or more <code>&lt;logger></code> elements,
   followed by at most one <code>&lt;root></code> element. The
   following diagram illustrates this basic structure.</p>

  
   <p align="left">
     <img src="images/chapters/configuration/basicSyntax.png" 
          alt="basic Syntax" title="Basic configuration file structure"/>
   </p>

    <p class="highlight">If you are unsure which case to use for a
    given tag name, just follow the <a
    href="http://en.wikipedia.org/wiki/CamelCase">camelCase
    convention</a> which is almost always the correct convention.</p>

    <h4 class="doAnchor" name="caseSensitivity">Case sensitivity of
    tag names</h4>
   
    <p>Since logback version 0.9.17, tag names pertaining to explicit
    rules are case insensitive.  For example,
    <code>&lt;logger></code>, <code>&lt;Logger></code> and
    <code>&lt;LOGGER></code> are valid configuration elements and will
    be interpreted in the same way. Note that XML well-formedness
    rules still apply, if you open a tag as <code>&lt;xyz></code> you
    must close it as <code>&lt;/xyz></code>, <code>&lt;/XyZ></code>
    will not work. As for <a href="onJoran.html#implicit">implicit
    rules</a>, tag names are case sensitive except for the first
    letter.  Thus, <code>&lt;xyz></code> and <code>&lt;Xyz></code> are
    equivalent but not <code>&lt;xYz></code>.  Implicit rules usually
    follow the <a
    href="http://en.wikipedia.org/wiki/CamelCase">camelCase</a>
    convention, common in the Java world. Since it is not easy to tell
    when a tag is associated with an explicit action and when it is
    associated with an implicit action, it is not trivial to say
    whether an XML tag is case-sensitive or insensitive with respect
    to the first letter. If you are unsure which case to use for a
    given tag name, just follow the camelCase convention which is
    almost always the correct convention.
    </p>

    <h4 class="doAnchor" name="loggerElement">Configuring loggers, or
    the <code>&lt;logger></code> element</h4>

    
    <p>At this point you should have at least some understanding of <a
    href="architecture.html#effectiveLevel">level inheritance</a> and
    the <a href="architecture.html#basic_selection">basic selection
    rule</a>. Otherwise, and unless you are an Egyptologist, logback
    configuration will be no more meaningful to you than are
    hieroglyphics.
    </p>

    <p>A logger is configured using the <code>&lt;logger></code>
    element. A <code>&lt;logger></code> element takes exactly one
    mandatory <span class="attr">name</span> attribute, an optional
    <span class="attr">level</span> attribute, and an optional <span
    class="attr">additivity</span> attribute, admitting the values
    <em>true</em> or <em>false</em>. The value of the <span
    class="attr">level</span> attribute admitting one of the
    case-insensitive string values TRACE, DEBUG, INFO, WARN, ERROR,
    ALL or OFF. The special case-insensitive value <em>INHERITED</em>,
    or its synonym <em>NULL</em>, will force the level of the logger
    to be inherited from higher up in the hierarchy. This comes in
    handy if you set the level of a logger and later decide that
    it should inherit its level.
    </p>

    <p class="highlight"> Note that unlike log4j, logback-classic does
    <em>not</em> close nor remove any previously referenced appenders
    when configuring a given logger.
    </p>

    <p>The <code>&lt;logger></code> element may contain zero or more
    <code>&lt;appender-ref></code> elements; each appender thus
    referenced is added to the named logger. Note that unlike log4j,
    logback-classic does <em>not</em> close nor remove any previously
    referenced appenders when configuring a given logger.
    </p>



   <h4 class="doAnchor" name="rootElement">Configuring the root
   logger, or the <code>&lt;root></code> element</h4>

   <p>The <code>&lt;root></code> element configures the root
   logger. It supports a single attribute, namely the <span
   class="attr">level</span> attribute. It does not allow any other
   attributes because the additivity flag does not apply to the root
   logger.  Moreover, since the root logger is already named as
   "ROOT", it does not allow a name attribute either. The value of the
   level attribute can be one of the case-insensitive strings TRACE,
   DEBUG, INFO, WARN, ERROR, ALL or OFF. Note that the level of the
   root logger cannot be set to INHERITED or NULL.
   </p>

   <p class="highlight">Note that unlike log4j, logback-classic does
   <em>not</em> close nor remove any previously referenced appenders
   when configuring the root logger.</p>

   <p> Similarly to the <code>&lt;logger></code> element, the
   <code>&lt;root></code> element may contain zero or more
   <code>&lt;appender-ref></code> elements; each appender thus
   referenced is added to the root logger. Note that unlike log4j,
   logback-classic does <em>not</em> close nor remove any previously
   referenced appenders when configuring the root logger.  </p>

   <h4>Example</h4>

   <p>Setting the level of a logger or root logger is as simple as
   declaring it and setting its level, as the next example
   illustrates. Suppose we are no longer interested in seeing any
   DEBUG messages from any component belonging to the
   "chapters.configuration" package. The following configuration file
   shows how to achieve that.
   </p>

   <p class="example">Example: Setting the level of a logger
   (logback-examples/src/main/resources/chapters/configuration/sample2.xml)</p>

   <pre id="sample2" class="prettyprint source">&lt;configuration>

  &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    &lt;!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    &lt;encoder>
      &lt;pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  <b>&lt;logger name="chapters.configuration" level="INFO"/></b>

  &lt;!-- Strictly speaking, the level attribute is not necessary since --&gt;
  &lt;!-- the level of the root level is set to DEBUG by default.       --&gt;
  &lt;root level="DEBUG">		
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>  
  
&lt;/configuration></pre>

  <p>When the above configuration file is given as argument to the
  <em>MyApp3</em> application, it will yield the following output:
  </p>
  
<pre class="source">17:34:07.578 [main] INFO  chapters.configuration.MyApp3 - Entering application.
17:34:07.578 [main] INFO  chapters.configuration.MyApp3 - Exiting application.</pre>

  <p>Note that the message of level DEBUG generated by the <a
  href="../xref/chapters/configuration/Foo.html">"chapters.configuration.Foo"</a>
  logger has been suppressed. See also the Foo class.</p>

  <p>You can configure the levels of as many loggers as you wish.  In
  the next configuration file, we set the level of the
  <em>chapters.configuration</em> logger to INFO but at the same time set the level
  of the <em>chapters.configuration.Foo</em> logger to <code>DEBUG</code>.
  </p>

  <p class="example">Example: Setting the level of multiple loggers
  (logback-examples/src/main/resources/chapters/configuration/sample3.xml)</p>
  
  <pre id="sample3" class="source prettyprint">&lt;configuration>

  &lt;appender name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    &lt;encoder>
      &lt;pattern>
        %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
     &lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  <b>&lt;logger name="chapters.configuration" level="INFO" /></b>
  <b>&lt;logger name="chapters.configuration.Foo" level="DEBUG" /></b>

  &lt;root level="DEBUG">
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>

&lt;/configuration></pre>

  <p>Running <code>MyApp3</code> with this configuration file will
  result in the following output on the console:
  </p>

<p class="prettyprint source">17:39:27.593 [main] INFO  chapters.configuration.MyApp3 - Entering application.
17:39:27.593 [main] DEBUG chapters.configuration.Foo - Did it again!
17:39:27.593 [main] INFO  chapters.configuration.MyApp3 - Exiting application.</p>

   <p>The table below list the loggers and their levels, after
   <code>JoranConfigurator</code> has configured logback with the
   <em>sample3.xml</em> configuration file.
   </p>

   <table class="bodyTable">
     <tr>
       <th>Logger name</th>
       <th>Assigned Level</th>
       <th>Effective Level</th>
     </tr>
     <tr>
       <td>root</td>
       <td><code>DEBUG</code></td>
       <td><code>DEBUG</code></td>
     </tr>
     <tr class="alt">
       <td>chapters.configuration</td>
       <td><code>INFO</code></td>
       <td><code>INFO</code></td>
     </tr>
     <tr>
       <td>chapters.configuration.MyApp3</td>
       <td><code>null</code></td>
       <td><code>INFO</code></td>
     </tr>
     <tr class="alt">
       <td>chapters.configuration.Foo</td>
       <td><code>DEBUG</code></td>
       <td><code>DEBUG</code></td>
     </tr>
   </table>

  <p>It follows that the two logging statements of level
  <code>INFO</code> in the <code>MyApp3</code> class as well as the
  DEBUG messages in <code>Foo.doIt()</code> are all enabled. Note that
  the level of the root logger is always set to a non-null value,
  DEBUG by default.
  </p>

  <p>Let us note that the <a
  href="architecture.html#basic_selection">basic-selection rule</a>
  depends on the effective level of the logger being invoked, not the
  level of the logger where appenders are attached. Logback will first
  determine whether a logging statement is enabled or not, and if
  enabled, it will invoke the appenders found in the logger hierarchy,
  regardless of their level. The configuration file
  <em>sample4.xml</em> is a case in point:
  </p>

  <p class="example">Example: Logger level sample
  (logback-examples/src/main/resources/chapters/configuration/sample4.xml)</p>

  <pre id="sample4" class="prettyprint source">&lt;configuration>

  &lt;appender name="STDOUT"
   class="ch.qos.logback.core.ConsoleAppender">
   &lt;encoder>
     &lt;pattern>
        %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
      &lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  <b>&lt;logger name="chapters.configuration" level="INFO" /></b>

  &lt;!-- turn OFF all logging (children can override) -->
  &lt;root <b>level="OFF"</b>>
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>

&lt;/configuration></pre>

  <p>The following table lists the loggers and their levels after
  applying the <em>sample4.xml</em> configuration file.
  </p>

  <table class="bodyTable">
    <tr>
      <th>Logger name</th>
      <th>Assigned Level</th>
      <th>Effective Level</th>
    </tr>
    <tr>
      <td>root</td>
      <td><code>OFF</code></td>
      <td><code>OFF</code></td>
    </tr>
    <tr class="alt">
      <td>chapters.configuration</td>
      <td><code>INFO</code></td>
      <td><code>INFO</code></td>
    </tr>
    <tr>
      <td>chapters.configuration.MyApp3</td>
      <td><code>null</code></td>
      <td><code>INFO</code></td>
    </tr>
    <tr class="alt">
      <td>chapters.configuration.Foo</td>
      <td><code>null</code></td>
      <td><code>INFO</code></td>
    </tr>
  </table>

  <p>The ConsoleAppender named <em>STDOUT</em>, the only configured
  appender in <em>sample4.xml</em>, is attached to the root logger
  whose level is set to <code>OFF</code>. However, running
  <em>MyApp3</em> with configuration script <em>sample4.xml</em> will
  yield:
  </p>

  <div class="source"><pre>17:52:23.609 [main] INFO chapters.configuration.MyApp3 - Entering application.
17:52:23.609 [main] INFO chapters.configuration.MyApp3 - Exiting application.</pre></div>

  <p>Thus, the level of the root logger has no apparent effect because
  the loggers in <code>chapters.configuration.MyApp3</code> and
  <code>chapters.configuration.Foo</code> classes are all enabled for the
  <code>INFO</code> level.  As a side note, the <em>chapters.configuration</em>
  logger exists by virtue of its declaration in the configuration file
  - even if the Java source code does not directly refer to it.
  </p>

  <h4 class="doAnchor" name="configuringAppenders">Configuring
  Appenders</h4>

  <p>An appender is configured with the <code>&lt;appender></code>
  element, which takes two mandatory attributes <span
  class="attr">name</span> and <span class="attr">class</span>.  The
  <span class="attr">name</span> attribute specifies the name of the
  appender whereas the <span class="attr">class</span> attribute
  specifies the fully qualified name of the appender class to
  instantiate. The <code>&lt;appender></code> element may contain zero
  or one <code>&lt;layout></code> elements, zero or more
  <code>&lt;encoder></code> elements and zero or more
  <code>&lt;filter></code> elements. Apart from these three common
  elements, <code>&lt;appender></code> elements may contain any number
  of elements corresponding to JavaBean properties of the appender
  class. Seamlessly supporting any property of a given logback
  component is one of the major strengths of <a
  href="onJoran.html">Joran</a> as discussed in a later chapter. The
  following diagram illustrates the common structure. Note that
  support for properties is not visible.
  </p>

  <p align="left">
    <img src="images/chapters/configuration/appenderSyntax.png" 
         alt="Appender Syntax" title="Appender element syntax"/>
  </p>

  <p>The <code>&lt;layout></code> element takes a mandatory class
  attribute specifying the fully qualified name of the layout class to
  instantiate.  As with the <code>&lt;appender></code> element,
  <code>&lt;layout></code> may contain other elements corresponding to
  properties of the layout instance. Since it's such a common case, if
  the layout class is <code>PatternLayout</code>, then the class
  attribute can be omitted as specified by <a
  href="onJoran.html#defaultClassMapping">default class mapping</a>
  rules.
  </p>

  <p>The <code>&lt;encoder></code> element takes a mandatory class
  attribute specifying the fully qualified name of the encoder class
  to instantiate. Since it's such a common case, if the encoder class
  is <code>PatternLayoutEncoder</code>, then the class attribute can
  be omitted as specified by <a
  href="onJoran.html#defaultClassMapping">default class mapping</a>
  rules.
  </p>

  <p>Logging to multiple appenders is as easy as defining the various
  appenders and referencing them in a logger, as the next
  configuration file illustrates:
  </p>

  <p class="example">Example: Multiple loggers
  (logback-examples/src/main/resources/chapters/configuration/multiple.xml)</p>

  <pre id="multiple" class="prettyprint source">&lt;configuration>

  &lt;appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
    &lt;file>myApp.log&lt;/file>

    &lt;encoder>
      &lt;pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;appender name="<b>STDOUT</b>" class="ch.qos.logback.core.ConsoleAppender">
    &lt;encoder>
      &lt;pattern>%msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="debug">
    <b>&lt;appender-ref ref="FILE" /></b>
    <b>&lt;appender-ref ref="STDOUT" /></b>
  &lt;/root>
&lt;/configuration></pre>

  <p>These configuration scripts define two appenders called
  <em>FILE</em> and <em>STDOUT</em>.  The <em>FILE</em> appender logs
  to a file called <em>myApp.log</em>. The encoder for this appender
  is a <code>PatternLayoutEncoder</code> that outputs the date, level,
  thread name, logger name, file name and line number where the log
  request is located, the message and line separator character(s).
  The second appender called <code>STDOUT</code> outputs to the
  console.  The encoder for this appender outputs only the message
  string followed by a line separator.
  </p>

  <p>The appenders are attached to the root logger by referencing them
  by name within an <em>appender-ref</em> element. Note that each
  appender has its own encoder. Encoders are usually not designed to
  be shared by multiple appenders. The same is true for layouts. As
  such, logback configuration files do not provide any syntactical
  means for sharing encoders or layouts.
  </p>

  <h4 class="doAnchor" name="cumulative">Appenders accumulate
  </h4>

  <p>By default, <b>appenders are cumulative</b>: a logger will log to
  the appenders attached to itself (if any) as well as all the
  appenders attached to its ancestors.  Thus, attaching the same
  appender to multiple loggers will cause logging output to be
  duplicated.
  </p>

  <p class="example">Example: Duplicate appender
  (logback-examples/src/main/resources/chapters/configuration/duplicate.xml)</p>

  <pre id="duplicate" class="prettyprint source">&lt;configuration>

  &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    &lt;encoder>
      &lt;pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;logger name="chapters.configuration">
    &lt;appender-ref ref="STDOUT" />
  &lt;/logger>

  &lt;root level="debug">
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>
&lt;/configuration></pre>

  <p>Running <code>MyApp3</code> with <em>duplicate.xml</em> will
  yield the following output:
  </p>

<p class="source">14:25:36.343 [main] INFO  chapters.configuration.MyApp3 - Entering application.
14:25:36.343 [main] INFO  chapters.configuration.MyApp3 - Entering application.
14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!
14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!
14:25:36.359 [main] INFO  chapters.configuration.MyApp3 - Exiting application.
14:25:36.359 [main] INFO  chapters.configuration.MyApp3 - Exiting application.</p>

  <p>Notice the duplicated output. The appender named <em>STDOUT</em>
  is attached to two loggers, to root and to
  <em>chapters.configuration</em>. Since the root logger is the
  ancestor of all loggers and <em>chapters.configuration</em> is the
  parent of both <em>chapters.configuration.MyApp3</em> and
  <em>chapters.configuration.Foo</em>, each logging request made with
  these two loggers will be output twice, once because <em>STDOUT</em>
  is attached to <em>chapters.configuration</em> and once because it
  is attached to <em>root</em>.
  </p>

  <p>Appender additivity is not intended as a trap for new users.  It
  is quite a convenient logback feature. For instance, you can
  configure logging such that log messages appear on the console (for
  all loggers in the system) while messages only from some specific
  set of loggers flow into a specific appender.
  </p>

  <p class="example">Example: Multiple appender
  (logback-examples/src/main/resources/chapters/configuration/restricted.xml)</p>

  <pre id="restricted" class="prettyprint source">&lt;configuration>

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
    &lt;file>myApp.log&lt;/file>
    &lt;encoder>
      &lt;pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    &lt;encoder>
      &lt;pattern>%msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;logger name="chapters.configuration">
    &lt;appender-ref ref="FILE" />
  &lt;/logger>

  &lt;root level="debug">
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>
&lt;/configuration></pre>

  <p>In this example, the console appender will log all the messages
  (for all loggers in the system) whereas only logging requests
  originating from the <em>chapters.configuration</em> logger and its
  children will go into the <em>myApp.log</em> file.
  </p>
	
  <h4 class="doAnchor" name="overrridingCumulativity">Overriding the
  default cumulative behaviour</h4>

  <p>In case the default cumulative behavior turns out to be
  unsuitable for your needs, you can override it by setting the
  additivity flag to false.  Thus, a branch in your logger tree may
  direct output to a set of appenders different from those of the rest
  of the tree.
  </p>

  <p class="example">Example: Additivity flag
  (logback-examples/src/main/resources/chapters/configuration/additivityFlag.xml)</p>

  <pre id="additivityFlag" class="prettyprint source">&lt;configuration>

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
    &lt;file>foo.log&lt;/file>
    &lt;encoder>
      &lt;pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    &lt;encoder>
      &lt;pattern>%msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;logger name="chapters.configuration.Foo" <b>additivity="false"</b>>
    &lt;appender-ref ref="FILE" />
  &lt;/logger>

  &lt;root level="debug">
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>
&lt;/configuration></pre>

  <p>This example, the appender named <em>FILE</em> is attached to the
  <em>chapters.configuration.Foo</em> logger. Moreover, the <em>chapters.configuration.Foo</em>
  logger has its additivity flag set to false such that its logging
  output will be sent to the appender named <em>FILE</em> but not to
  any appender attached higher in the hierarchy. Other loggers remain
  oblivious to the additivity setting of the <em>chapters.configuration.Foo</em>
  logger.  Running the <code>MyApp3</code> application with the
  <em>additivityFlag.xml</em> configuration file will output results
  on the console from the <em>chapters.configuration.MyApp3</em> logger.  However,
  output from the <em>chapters.configuration.Foo</em> logger will appear in the
  <em>foo.log</em> file and only in that file.
  </p>

  <h3 class="doAnchor" name="contextName">Setting the context
  name</h3>

  <p>As mentioned <a href="architecture.html#LoggerContext">in an
  earlier chapter</a>, every logger is attached to a logger
  context. By default, the logger context is called
  "default". However, you can set a different name with the help of
  the <code>&lt;contextName></code> configuration directive. Note that
  once set, the logger context name <a
  href="../apidocs/ch/qos/logback/core/ContextBase.html#setName(java.lang.String)">cannot
  be changed</a>. Setting the context name is a simple and
  straightforward method in order to distinguish between multiple
  applications logging to the same target.
  </p>
  
  <p class="example">Example: Set the context name and display it
  (logback-examples/src/main/resources/chapters/configuration/contextName.xml)</p>

  <pre id="contextName" class="prettyprint source">&lt;configuration>
  <b>&lt;contextName>myAppName&lt;/contextName></b>
  &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    &lt;encoder>
      &lt;pattern>%d <b>%contextName</b> [%t] %level %logger{36} - %msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="debug">
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>
&lt;/configuration></pre>

  <p>This last example illustrates naming of the logger
  context. Adding the <a
  href="layouts.html#conversionWord">contextName conversion word</a>
  in layout's pattern will output the said name.</p>
  
  <!-- =============================================================== -->
 
  <h3 class="doAnchor" name="variableSubstitution">Variable
  substitution</h3>

  <p><span class="label">Note</span> Earlier versions of this document
  used the term "property substitution" instead of the term
  "variable". Please consider both terms interchangeable although the
  latter term conveys a clearer meaning.
  </p>

  <p>As in many scripting languages, logback configuration files
  support definition and substitution of variables. Variables have a
  <a href="#scopes">scope</a> (see below). Moreover, variables can be
  defined within the configuration file itself, in an external file,
  in an external resource or even computed and <a
  href="#definingPropsOnTheFly">defined on the fly</a>.
  </p>

  <p class="highlight">Variable substitution can occur at any point in
  a configuration file where a value can be specified.</p>

  <p>Variable substitution can occur at any point in a configuration
  file where a value can be specified. The syntax of variable
  substitution is similar to that of Unix shells. The string between
  an opening <em>${</em> and closing <em>}</em> is interpreted as a
  reference to the <em>value</em> of the property.  For property
  <em>aName</em>, the string "${aName}" will be replaced with the
  value held by the <em>aName</em> property.
  </p>

  

  <p>As they often come in handy, the HOSTNAME and CONTEXT_NAME
  variables are automatically defined and have context scope. Given
  that in some environments it may take some time to compute the
  hostname, its value is computed lazily (only when needed). Moreover,
  HOSTNAME can be set from within the <a
  href="#definingProps">configuration directly.</a>
  </p>

   <h4 class="doAnchor" name="definingProps">Defining variables</h4>

  <p>Variables can be defined one at a time in the configuration file
  itself or loaded wholesale from an external properties file or an
  external resource. For historical reasons, the XML element for
  defining variables is <code>&lt;property&gt;</code> although in
  logback 1.0.7 and later the element <code>&lt;variable></code> can
  be used interchangeably.</p>

  <p>The next example shows a variable declared at the beginning of
  the configuration file. It is then used further down the file to
  specify the location of the output file.
  </p>

  <p class="example">Example: Simple Variable substitution
  (logback-examples/src/main/resources/chapters/configuration/variableSubstitution1.xml)
  </p>

  <pre id="variableSubstitution1" class="prettyprint source">&lt;configuration>

  <b>&lt;property name="USER_HOME" value="/home/sebastien" /></b>

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <b>&lt;file>${USER_HOME}/myApp.log&lt;/file></b>
    &lt;encoder>
      &lt;pattern>%msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="debug">
    &lt;appender-ref ref="FILE" />
  &lt;/root>
&lt;/configuration></pre>

  <p>The next example shows the use of a System property to achieve
  the same result. The property is not declared in the configuration
  file, thus logback will look for it in the System properties. Java
  system properties can be set on the command line as shown next:
  </p>
  
  <p class="source">java -DUSER_HOME="/home/sebastien" MyApp2</p>

  <p class="example">Example: System Variable substitution
  (logback-examples/src/main/resources/chapters/configuration/variableSubstitution2.xml)
  </p>

  <pre id="variableSubstitution2" class="prettyprint source">&lt;configuration>

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <b>&lt;file>${USER_HOME}/myApp.log&lt;/file></b>
    &lt;encoder>
      &lt;pattern>%msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="debug">
    &lt;appender-ref ref="FILE" />
  &lt;/root>
&lt;/configuration></pre>

  
  <p>When multiple variables are needed, it may be more convenient to
  create a separate file that will contain all the variables. Here is
  how one can do such a setup.
  </p>

  <p class="example">Example: Variable substitution using a
  separate file
  (logback-examples/src/main/resources/chapters/configuration/variableSubstitution3.xml)
  </p>

  <pre id="variableSubstitution3" class="prettyprint source">&lt;configuration>

  <b>&lt;property file="src/main/java/chapters/configuration/variables1.properties" /></b>

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <b>&lt;file>${USER_HOME}/myApp.log&lt;/file></b>
     &lt;encoder>
       &lt;pattern>%msg%n&lt;/pattern>
     &lt;/encoder>
   &lt;/appender>

   &lt;root level="debug">
     &lt;appender-ref ref="FILE" />
   &lt;/root>
&lt;/configuration></pre>

   <p>This configuration file contains a reference to a file named
   <em>variables1.properties</em>.  The variables contained in that
   file will be read and then defined within local scope. Here is what
   the <em>variable.properties</em> file might look like.
   </p>

   <em>Example: Variable file
   (logback-examples/src/main/resources/chapters/configuration/variables1.properties)</em>

   <pre class="source">USER_HOME=/home/sebastien</pre>

   <p>You may also reference a resource on the class path instead of a
   file.</p>

  <pre class="prettyprint source">&lt;configuration>

  <b>&lt;property resource="resource1.properties" /></b>

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <b>&lt;file>${USER_HOME}/myApp.log&lt;/file></b>
     &lt;encoder>
       &lt;pattern>%msg%n&lt;/pattern>
     &lt;/encoder>
   &lt;/appender>

   &lt;root level="debug">
     &lt;appender-ref ref="FILE" />
   &lt;/root>
&lt;/configuration></pre>


   <h4 class="doAnchor" name="scopes">Scopes</h4>

   <p>A property can be defined for insertion in <em>local scope</em>,
   in <em>context scope</em>, or in <em>system scope</em>. Local scope
   is the default. Although it is possible to read variables from the
   OS environment, it is not possible to write into the OS
   environment.</p>


   <p><span class="label">local scope</span> A property with local
   scope exists from the point of its definition in a configuration
   file until the end of interpretation/execution of said
   configuration file. As a corollary, each time a configuration file
   is parsed and executed, variables in local scope are defined
   anew.</p>

   <p><span class="label">context scope</span> A property with context
   scope is inserted into the context and lasts as long as the context
   or until it is cleared.  Once defined, a property in context scope
   is part of the context. As such, it is available in all logging
   events, including those sent to remote hosts via serialization. 
   </p>

   <p><span class="label">system scope</span> A property with system
   scope is inserted into the JVM's system properties and lasts as
   long as the JVM or until it is cleared.
   </p>
 
   <p class="highlight">Properties are looked up in the the local
   scope first, in the context scope second, in the system properties
   scope third, and in the OS environment last.
   </p>

   <p>During substitution, properties are looked up in the local scope
   first, in the context scope second, in the system properties scope
   third, and in the <a
   href="http://docs.oracle.com/javase/tutorial/essential/environment/env.html">OS
   environment</a> fourth and last.
   </p>

   <p>The <span class="attr">scope</span> attribute of the
   <code>&lt;property></code> element, <code>&lt;define></code>
   element or the <code>&lt;insertFromJNDI></code> element can be used
   to set the scope of a property. The <span class="attr">scope</span>
   attribute admits "local", "context" and "system" strings as
   possible values. If not specified, the scope is always assumed to
   be "local".
   </p>

   <p class="example">Example: A variable defined in "context" scope
   (logback-examples/src/main/resources/chapters/configuration/contextScopedVariable.xml)
   </p>

  <pre id="contextScopedVariable" class="prettyprint source">&lt;configuration>

  &lt;property <b class="big">scope="context"</b> name="nodeId" value="firstNode" />

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <b>&lt;file>/opt/${nodeId}/myApp.log&lt;/file></b>
    &lt;encoder>
      &lt;pattern>%msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="debug">
    &lt;appender-ref ref="FILE" />
  &lt;/root>
&lt;/configuration></pre>

   <p>In the above example, given that the <em>nodeId</em> property is
   defined in the context scope, it will be available in every logging
   event, even those sent to remote hosts via serialization.</p>


  <h3 class="doAnchor" name="defaultValuesForVariables">Default values
  for variables</h3>

  <p>Under certain circumstances, it may be desirable for a variable
  to have a default value if it is not declared or its value is
  null. As in the <a
  href="http://tldp.org/LDP/abs/html/parameter-substitution.html">Bash
  shell</a>, default values can be specified using the <b>":-"</b>
  operator. For example, assuming the variable named <em>aName</em> is
  not defined, <code>"${aName<b>:-golden</b>}"</code> will be
  interpreted as "golden".</p>

   <h3 class="doAnchor" name="nestedSubst">Nested variables</h3>

   <p>Variable nesting is fully supported. Both the name,
   default-value and value definition of a variable can reference
   other variables.</p>


   <h4>value nesting</h4>
   <p>The value definition of a variable can contain references to
   other variables. Suppose you wish to use variables to specify not
   only the destination directory but also the file name, and combine
   those two variables in a third variable called "destination". The
   properties file shown below gives an example.
   </p>

   <p class="example">Example: Nested variable references
   (logback-examples/src/main/resources/chapters/configuration/variables2.properties)</p>

   <pre class="source">USER_HOME=/home/sebastien
fileName=myApp.log
<b>destination=${USER_HOME}/${fileName}</b></pre>

    <p>Note that in the properties file above, "destination" is
    composed from two other variables, namely "USER_HOME" and
    "fileName".
    </p>
    
    <em>Example: Variable substitution using
    a separate file
    (logback-examples/src/main/resources/chapters/configuration/variableSubstitution4.xml)</em>

    <pre class="prettyprint source">&lt;configuration>

  &lt;property file="variables2.properties" />

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <b>&lt;file>${destination}&lt;/file></b>
    &lt;encoder>
      &lt;pattern>%msg%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="debug">
    &lt;appender-ref ref="FILE" />
  &lt;/root>
&lt;/configuration></pre>


   <h4>name nesting</h4>

   <p>When referencing a variable, the variable name may contain a
   reference to another variable. For example, if the variable named
   "userid" is assigned the value "alice", then
   "${${userid}.password}" references the variable with the name
   "alice.password".</p>

   <h4>default value nesting</h4>

   <p>The default value of a variable can reference a another
   variable.  For example, assuming the variable 'id' is unassigned
   and the variable 'userid' is assigned the value "alice", then the
   expression "${id<b>:-</b>${userid}}" will return "alice".
   </p>


  <!-- ==============================================================
       -->
  <h3 class="doAnchor" name="hostname">HOSTNAME property</h3>

  <p>As it often comes in handy, the <code>HOSTNAME</code> property is
  defined automatically during configuration with context scope.</p>

  <!-- ============================================================== -->
  <h3 class="doAnchor" name="context_name">CONTEXT_NAME property</h3>

  <p>As its name indicates, the <code>CONTEXT_NAME</code> property
  corresponds to the name of the current logging context.</p>

  <!-- ============================================================== -->
  
  <h3 class="doAnchor" name="timestamp">Setting a timestamp</h3>

  <p>The <em>timestamp</em> element can define a property according to
  current date and time. The <em>timestamp</em> element is <a
  href="appenders.html#uniquelyNamed">explained in a subsequent
  chapter</a>.</p>

  <!-- ============================================================== -->
  <h3 class="doAnchor" name="definingPropsOnTheFly">Defining
  properties on the fly</h3>

  <p>You may define properties dynamically using the
  <code>&lt;define></code> element. The define element takes two
  mandatory attributes: <span class="attr">name</span> and <span
  class="attr">class</span>. The <span class="attr">name</span>
  attribute designates the name of the property to set whereas the
  <span class="attr">class</span> attribute designates any class
  implementing the <a
  href="../xref/ch/qos/logback/core/spi/PropertyDefiner.html">PropertyDefiner</a>
  interface. The value returned by the <code>getPropertyValue</code>()
  method of the <code>PropertyDefiner</code> instance will be the
  value of the named property. You may also specify a <a
  href="#scopes">scope</a> for the named property by specifying a
  <span class="attr">scope</span> attribute.
  </p>

  <p>Here is an example.</p>

  <pre class="prettyprint source">&lt;configuration>

  &lt;define name="rootLevel" class="a.class.implementing.PropertyDefiner">
    &lt;shape>round&lt;/shape>
    &lt;color>brown&lt;/color>
    &lt;size>24&lt;/size>
  &lt;/define>
 
  &lt;root level="${rootLevel}"/>
&lt;/configuration></pre>

  <p>In the above example, shape, color and size are properties of
  "a.class.implementing.PropertyDefiner". As long as there is a setter
  for a given property in your implementation of the
  <code>PropertyDefiner</code> instance, logback will inject the
  appropriate values as specified in the configuration file. </p>

 

  <p>At the present time, logback does ships with two fairly simple
  implementations of <code>PropertyDefiner</code>.  
  </p>

  <table class="bodyTable striped">
    <tr>
      <th>Implementation name</th>
      <th>Description</th>
    </tr>

    <tr>
      <td><a
      href="../apidocs/ch/qos/logback/core/property/CanonicalHostNamePropertyDefiner.html"><code>CanonicalHostNamePropertyDefiner</code></a>
      </td>
      <td>Set the named variable to the canonical host name of the
      local host. Note that obtaining the canonical host name may take several seconds.
      </td>
    </tr>

    <tr>
      <td><a
      href="../apidocs/ch/qos/logback/core/property/FileExistsPropertyDefiner.html"><code>FileExistsPropertyDefiner</code></a>
      </td>
      <td>Set the named variable to "true" if the file specified by
      <span class="prop">path</span> property exists, to "false"
      otherwise.
      </td>
    </tr>

    <tr>
      <td><a
      href="../apidocs/ch/qos/logback/core/property/FileExistsPropertyDefiner.html"><code>ResourceExistsPropertyDefiner</code></a>
      </td>

      <td>Set the named variable to "true" if the <span
      class="prop">resource</span> specified by the user is available
      on the class path, to "false" otherwise.
      </td>
    </tr>
  </table>

  
  <!-- ============================================================== -->

  <h3 class="doAnchor" name="conditional">Conditional processing of
  configuration files</h3>
  
  <p>Developers often need to juggle between several logback
  configuration files targeting different environments such as
  development, testing and production. These configuration files have
  substantial parts in common differing only in a few places. To avoid
  duplication, logback supports conditional processing of
  configuration files with the help of <code>&lt;if></code>,
  <code>&lt;then></code> and <code>&lt;else></code> elements so that a
  single configuration file can adequately target several
  environments. Note that conditional processing requires the <a
  href="../setup.html#janino">Janino library</a>.
  </p>

  <p>The general format for conditional statements is shown below.</p>

  <pre class="prettyprint source">
   &lt;!-- if-then form -->
   &lt;if condition="some conditional expression">
    &lt;then>
      ...
    &lt;/then>
  &lt;/if>
  
  &lt;!-- if-then-else form -->
  &lt;if condition="some conditional expression">
    &lt;then>
      ...
    &lt;/then>
    &lt;else>
      ...
    &lt;/else>    
  &lt;/if></pre>  

  
  
  <p>The condition is a Java expression in which only context
  properties or system properties are accessible. For a key passed as
  argument, the <code>property</code>() or its shorter equivalent
  <code>p</code>() methods return the String value of the property.
  For example, to access the value of a property with key "k", you
  would write <code>property("k")</code> or equivalently
  <code>p("k")</code>. If the property with key "k" is undefined, the
  property method will return the empty string and not null. This
  avoids the need to check for null values.</p>

  <p>The <code>isDefined()</code> method can be used to check whether
  a property is defined. For example, to check whether the property
  "k" is defined you would write <code>isDefined("k")</code>
  Similarly, if you need to check whether a property is null, the
  <code>isNull()</code> method is provided. Example:
  <code>isNull("k")</code>.</p>

  
  <pre class="prettyprint source">&lt;configuration debug="true">

  <b>&lt;if condition='property("HOSTNAME").contains("torino")'></b>
    <b>&lt;then></b>
      &lt;appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
        &lt;encoder>
          &lt;pattern>%d %-5level %logger{35} - %msg %n&lt;/pattern>
        &lt;/encoder>
      &lt;/appender>
      &lt;root>
        &lt;appender-ref ref="CON" />
      &lt;/root>
    <b>&lt;/then></b>
  <b>&lt;/if></b>

  &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
    &lt;file>${randomOutputDir}/conditional.log&lt;/file>
    &lt;encoder>
      &lt;pattern>%d %-5level %logger{35} - %msg %n&lt;/pattern>
   &lt;/encoder>
  &lt;/appender>

  &lt;root level="ERROR">
     &lt;appender-ref ref="FILE" />
  &lt;/root>
&lt;/configuration></pre>

  
  <p>Conditional processing is supported <em>anywhere</em> within the
  <code>&lt;configuration></code> element. Nested if-then-else
  statements are also supported. However, XML syntax is awfully
  cumbersome and is ill suited as the foundation of a general purpose
  programming language.  Consequently, too many conditionals will
  quickly render your configuration files incomprehensible to subsequent
  readers, including yourself.
  </p>


  <!-- ============================================================== -->

   <h3 class="doAnchor" name="insertFromJNDI">Obtaining variables from
   JNDI</h3>

   <p>Under certain circumstances, you may want to make use of
   env-entries stored in JNDI. The <code>&lt;insertFromJNDI></code>
   configuration directive extracts an env-entry stored in JNDI and
   inserts the property in local scope with key specified by the <span
   class="attr">as</span> attribute. As all properties, it is possible
   to insert the new property into a <a href="#scopes">different
   scope</a> with the help of the <em>scope</em> attribute.
   </p>

   <p class="example">Example: Insert as properties env-entries
   obtained via JNDI
   (logback-examples/src/main/resources/chapters/configuration/insertFromJNDI.xml)</p>

   <pre class="prettyprint source">&lt;configuration>
  <b>&lt;insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
  <b>&lt;contextName><span class="green">${appName}</span>&lt;/contextName></b>

  &lt;appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    &lt;encoder>
      &lt;pattern>%d ${CONTEXT_NAME} %level %msg %logger{50}%n&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>

  &lt;root level="DEBUG">
    &lt;appender-ref ref="CONSOLE" />
  &lt;/root>
&lt;/configuration></pre>

  <p>In this last example, the "java:comp/env/appName" env-entry is
  inserted as the <span class="variable">appName</span> property. Note
  that the <code>&lt;contextName></code> directive sets the context
  name based on the value of the <span class="variable">appName</span>
  property inserted by the previous <code>&lt;insertFromJNDI></code>
  directive.
  </p>

  <h3 class="doAnchor" name="fileInclusion">File inclusion</h3>

  <p>Joran supports including parts of a configuration file from
  another file. This is done by declaring a <code>&lt;include></code>
  element, as shown below:
  </p>

  <p class="example">Example: File include
  (logback-examples/src/main/resources/chapters/configuration/containingConfig.xml)</p>

  <pre class="prettyprint source">&lt;configuration>
  <b>&lt;include file="src/main/java/chapters/configuration/includedConfig.xml"/></b>

  &lt;root level="DEBUG">
    &lt;appender-ref ref="includedConsole" />
  &lt;/root>

&lt;/configuration></pre>

  <p>The target file MUST have its elements nested inside an
  <code>&lt;included></code> element. For example, a
  <code>ConsoleAppender</code> could be declared as:
  </p>

  <p class="example">Example: File include
  (logback-examples/src/main/resources/chapters/configuration/includedConfig.xml)</p>

  <pre class="source"><b class="green big">&lt;included></b>
  &lt;appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
    &lt;encoder>
      &lt;pattern>"%d - %m%n"&lt;/pattern>
    &lt;/encoder>
  &lt;/appender>
<b class="green big">&lt;/included></b></pre>


  <p>Again, please note the mandatory
  <code class="big green">&lt;included></code> element.</p>

  <p>The contents to include can be referenced as a file, as a
  resource, or as a URL.</p>

  <ul>

    <li><b>As a file:</b><br/> To include a file use the <span
    class="attr">file</span> attribute. You can use relative paths but
    note that the current directory is defined by the application and
    is not necessarily related to the path of the configuration
    file.</li>

    <li><p><b>As a resource:</b><br/> To include a resource, i.e a
    file found on the class path, use the <span
    class="attr">resource</span> attribute.</p>

    <pre class="prettyprint source">&lt;include resource="includedConfig.xml"/></pre>
    
    </li>

    <li><p><b>As a URL:</b><br/> To include the contents of a URL use
    the <span class="attr">url</span> attribute.</p>

    <pre class="prettyprint source">&lt;include url="http://some.host.com/includedConfig.xml"/></pre>

    </li>
  </ul>

  <p>If it cannot find the file to be included, logback will complain
  by printing a status message.  In case the included file is
  optional, you can suppress the warning message by setting <span
  class="attr">optional</span> attribute to <code>true</code> in the
  <code>&lt;include></code> element.</p>


  <pre class="prettyprint source">&lt;include optional="true" ..../></pre>

  <!-- ==================== ContextListener =================== -->
  <h2 class="doAnchor" name="contextListener">Adding a context
  listener</h2>

  <p>Instances of the <a
  href="../xref/ch/qos/logback/classic/spi/LoggerContextListener.html">LoggerContextListener</a>
  interface listen to events pertaining to the lifecycle of a logger
  context. 
  </p>


  <p><code>JMXConfigurator</code> is one implementation of the
  <code>LoggerContextListener</code> interface. It is described in a <a
  href="jmxConfig.html">subsequent chapter</a>.
  </p>

  <h3 class="doAnchor"
  name="LevelChangePropagator">LevelChangePropagator</h3>

  <p>As of version 0.9.25, logback-classic ships with <a
  href="../xref/ch/qos/logback/classic/jul/LevelChangePropagator.html">LevelChangePropagator</a>,
  an implementation of <code>LoggerContextListener</code> which
  propagates changes made to the level of any logback-classic logger
  onto the java.util.logging framework. Such propagation eliminates
  the performance impact of disabled log statements. Instances of <a
  href="http://download.oracle.com/javase/1.5.0/docs/api/java/util/logging/LogRecord.html?is-external=true">LogRecord</a>
  will be sent to logback (via SLF4J) only for enabled log
  statements. This makes it reasonable for real-world applications to
  use the <a
  href="http://www.slf4j.org/legacy.html#jul-to-slf4j">jul-to-slf4j</a>
  bridge.
  </p>


  <p>The contextListener element can be used to install <code>LevelChangePropagator</code> as shown next.</p>
  
  <pre class="prettyprint source">&lt;configuration debug="true">
  <b>&lt;contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/></b>
  .... 
&lt;/configuration></pre>

  <p>Setting the <span class="option">resetJUL</span> property of
  LevelChangePropagator will reset all previous level configurations
  of all j.u.l. loggers. However, previously installed handlers will be
  left untouched.</p>

  <pre class="prettyprint source">&lt;configuration debug="true">
  &lt;contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
    <b>&lt;resetJUL>true&lt;/resetJUL></b>
  &lt;/contextListener>
  ....
&lt;/configuration></pre>
  <p>
  </p>

  <script src="../templates/footer.js" type="text/javascript"></script>
  </div>
</div>
</body>
</html>
